package com.advertisementsystem.Controller;

import com.advertisementsystem.Dto.LoginUser;
import com.advertisementsystem.Dto.ScheduleDTO;
import com.advertisementsystem.Dto.ScheduleStatusUpdateDTO;
import com.advertisementsystem.Dto.ScheduleUpdateDTO;
import com.advertisementsystem.Exception.ResponseResult;
import com.advertisementsystem.Mapper.AdScheduleMapper;
import com.advertisementsystem.Mapper.DeviceMapper;
import com.advertisementsystem.Servie.DeviceService;
import com.advertisementsystem.Servie.ScheduleService;
import com.advertisementsystem.entity.Device;
import com.advertisementsystem.entity.Schedule;
import com.advertisementsystem.vo.AdSchedule;
import com.advertisementsystem.vo.AdScheduleVO;
import com.advertisementsystem.vo.ScheduleVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/schedule")
@Slf4j
public class ScheduleController {
    @Autowired
    private ScheduleService scheduleService;
    /**
     * 创建广告排期
     *
     * @param dto 排期信息，包含：
     *            - 广告ID
     *            - 设备ID
     *            - 开始时间
     *            - 结束时间
     *            - 播放时段列表
     *            - 备注
     * @return 创建成功的排期信息
     */
    @PostMapping
    @PreAuthorize("hasRole('DEVICE_OWNER')")
    public ResponseResult<?> createSchedule(@RequestBody @Valid ScheduleDTO dto) {
        log.info("创建广告排期, 排期信息: {}", dto);
        return ResponseResult.success(scheduleService.createSchedule(dto));
    }
    /**
     * 获取设备的排期列表
     *
     * @param deviceId  设备ID
     * @param startDate 开始日期（格式：yyyy-MM-dd）
     * @param endDate   结束日期（格式：yyyy-MM-dd）
     * @return 指定日期范围内的设备排期列表
     */
    @GetMapping("/device/{deviceId}")
    public ResponseResult<?> getDeviceSchedule(
            @PathVariable Long deviceId,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
        return ResponseResult.success(scheduleService.getDeviceSchedule(deviceId, startDate, endDate));
    }
    /**
     * 获取广告的排期列表
     *
     * @param adId 广告ID
     * @return 该广告的所有排期信息
     */
    @GetMapping("/advertisement/{adId}")
    public ResponseResult<List<ScheduleVo> > getAdvertisementSchedule(@PathVariable Long adId) {
        return ResponseResult.success(scheduleService.getAdvertisementSchedule(adId));
    }
    /**
     * 更新排期信息
     *
     * @param id  排期ID
     * @param dto 更新的排期信息，可包含：
     *            - 开始时间
     *            - 结束时间
     *            - 播放时段列表
     *            - 备注
     * @return 更新后的排期信息
     */
    @PutMapping("/{id}")
    @PreAuthorize("hasRole('DEVICE_OWNER')")
    public ResponseResult<?> updateSchedule(
            @PathVariable Long id,
            @RequestBody @Valid ScheduleUpdateDTO dto) {
        return ResponseResult.success(scheduleService.updateSchedule(id, dto));
    }

    /**
     * 检查协商是否已创建排期
     *
     * @param negotiationId 协商ID
     * @return 是否已创建排期（true/false）
     */
    @GetMapping("/negotiation/{negotiationId}/has-schedule")
    public ResponseResult<?> checkNegotiationHasSchedule(@PathVariable Long negotiationId) {
        log.info("检查协商是否已创建排期, 协商ID: {}", negotiationId);
        boolean hasSchedule = scheduleService.checkNegotiationHasSchedule(negotiationId);
        return ResponseResult.success(hasSchedule);
    }


    /**
     * 获取当前广告主的所有排期列表
     */
    @GetMapping("/advertiser")
    // @PreAuthorize("hasRole('ROLE_ADVERTISER')")
    public ResponseResult<Page<ScheduleVo>> getAdvertiserSchedules(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String adTitle,
            @RequestParam(required = false) String deviceName,
            @RequestParam(required = false) String status) {

        // 获取当前登录用户ID
        // 检查权限
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();

        Long advertiserId = loginUser.getUser().getId();


        log.info("查询广告主(ID:{})的排期列表, 页码:{}, 每页数量:{},设备状态{}", advertiserId, pageNum, pageSize,status);

        Page<ScheduleVo> page = scheduleService.getAdvertiserSchedules(
                advertiserId, pageNum, pageSize, adTitle, deviceName, status);

        return ResponseResult.success(page);
    }
    /**
     * 获取排期详情
     */
    @GetMapping("/{id}")
    // @PreAuthorize("hasRole('ROLE_ADVERTISER')")
    public ResponseResult<ScheduleVo> getScheduleDetail(@PathVariable Long id) {
        // 获取当前登录用户ID
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();

        Long advertiserId = loginUser.getUser().getId();

        log.info("广告主(ID:{})查询排期详情, 排期ID:{}", advertiserId, id);

        ScheduleVo scheduleVo = scheduleService.getScheduleDetailForAdvertiser(id, advertiserId);

        if (scheduleVo == null) {
            return ResponseResult.error("排期不存在或无权查看");
        }

        return ResponseResult.success(scheduleVo);
    }
    /**
     * 取消排期
     */
    @PostMapping("/{id}/cancel")
    // @PreAuthorize("hasRole('ROLE_ADVERTISER')")
    public ResponseResult<Void> cancelSchedule(@PathVariable Long id) {
        // 获取当前登录用户ID
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();

        Long advertiserId = loginUser.getUser().getId();

        // log.info("广告主(ID:{})取消排期, 排期ID:{}", advertiserId, id);

        boolean success = scheduleService.cancelScheduleForAdvertiser(id, advertiserId);

        if (!success) {
            return ResponseResult.error("取消排期失败，可能排期不存在、无权操作或状态不允许取消");
        }

        return ResponseResult.success();
    }


    /**
     * 获取排期列表
     */
    @GetMapping
    public ResponseResult<IPage<AdSchedule>> getScheduleList(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) Long deviceId,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate) {

        // 获取当前登录用户ID
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();
        Long userId = loginUser.getUser().getId();
        Page<Schedule> page = new Page<>(pageNum, pageSize);

        IPage<AdSchedule> result = scheduleService.getScheduleList(
                page, userId, status, deviceId, startDate, endDate);

        return ResponseResult.success(result);
    }

    /**
     * 更新排期状态
     */
    @PutMapping("/{id}/status")
    @PreAuthorize("hasRole('DEVICE_OWNER')")
    public ResponseResult<Boolean> updateScheduleStatus(
            @PathVariable("id") Long id,
            @RequestBody @Valid ScheduleStatusUpdateDTO statusUpdateDTO) {

        // 获取当前登录用户ID
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();
        Long userId = loginUser.getUser().getId();
        boolean success = scheduleService.updateStatus(id, statusUpdateDTO.getStatus(), userId);

        if (success) {
            return ResponseResult.success(true);
        } else {
            return ResponseResult.error("更新排期状态失败");
        }
    }
}